import os
from src.ui.i18n import _
from PySide6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QFormLayout,
    QPushButton, QFileDialog, QLineEdit, QMessageBox, QComboBox,
    QCheckBox, QGroupBox, QLabel, QTableWidget, QTableWidgetItem, QHeaderView
)
from PySide6.QtCore import Qt

from src.config import app_config
from src.processing.worker import ProcessingWorker
from src.utils.formatter import format_srt_file_standalone
from src.utils.logger import get_logger
from src.ui.widgets.generation_options_widget import GenerationOptionsWidget


class GenerationTab(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.worker = None
        self.logger = get_logger(__name__)
        
        self._setup_ui()
        self._connect_signals()
        self.retranslate_ui()

    def _setup_ui(self):
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(10, 15, 10, 10)
        main_layout.setSpacing(15)

        # --- Input Group ---
        self.input_group = QGroupBox()
        form_layout = QFormLayout(self.input_group)
        form_layout.setSpacing(10)

        self.media_path_edit = QLineEdit()
        self.media_path_button = QPushButton()
        media_layout = QHBoxLayout()
        media_layout.addWidget(self.media_path_edit)
        media_layout.addWidget(self.media_path_button)

        self.generation_options = GenerationOptionsWidget()

        self.media_path_label = QLabel()
        form_layout.addRow(self.media_path_label, media_layout)
        form_layout.addWidget(self.generation_options)
        main_layout.addWidget(self.input_group)

        # --- Status and History Group ---
        self.status_group = QGroupBox()
        status_layout = QVBoxLayout(self.status_group)
        
        self.status_label = QLabel()
        self.status_label.setStyleSheet("font-weight: bold; color: #e0e0e0;")
        status_layout.addWidget(self.status_label)

        self.history_table = QTableWidget()
        self.history_table.setColumnCount(4)
        self.history_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        self.history_table.setWordWrap(True)
        status_layout.addWidget(self.history_table)
        main_layout.addWidget(self.status_group)

        # --- Action Buttons ---
        self.format_button = QPushButton()
        self.process_button = QPushButton()
        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)
        self.stop_button.setStyleSheet("background-color: #bf616a;")

        button_layout = QHBoxLayout()
        button_layout.addWidget(self.format_button)
        button_layout.addStretch()
        button_layout.addWidget(self.stop_button)
        button_layout.addWidget(self.process_button)
        main_layout.addLayout(button_layout)

    def _connect_signals(self):
        self.media_path_button.clicked.connect(self.select_media_file)
        self.process_button.clicked.connect(self.start_processing)
        self.stop_button.clicked.connect(self.stop_processing)
        self.format_button.clicked.connect(self.run_formatter_standalone)

    def retranslate_ui(self):
        self.input_group.setTitle(_("Input Settings"))
        self.media_path_button.setText(_("Select Media File..."))
        
        self.media_path_label.setText(_("Media File:"))
        self.generation_options.retranslate_ui()

        self.status_group.setTitle(_("Status and History"))
        self.status_label.setText(_("Idle"))
        self.history_table.setHorizontalHeaderLabels([_("File Name"), _("Model"), _("Time (s)"), _("Status")])
        self.format_button.setText(_("Format SRT File"))
        self.process_button.setText(_("Start Generating Subtitles"))
        self.stop_button.setText(_("Stop"))

    def select_media_file(self):
        last_dir = app_config.get("paths.last_media_dir", os.path.expanduser("~"))
        file_path, _filter = QFileDialog.getOpenFileName(
            self, _("Select Media File"), last_dir, _("Media Files (*.mp4 *.mkv *.avi *.mov *.mp3 *.wav *.flac *.aac)"),
        )
        if file_path:
            self.media_path_edit.setText(file_path)
            app_config.set("paths.last_media_dir", os.path.dirname(file_path), emit_signal=False)
            app_config.save(emit_signal=False)

    def start_processing(self):
        media_path = self.media_path_edit.text()
        if not media_path or not os.path.exists(media_path):
            QMessageBox.warning(self, _("Warning"), _("Invalid media file path!"))
            return
        
        generation_opts = self.generation_options.get_options()
        whisper_model_data = generation_opts.get("whisper_model")

        if not whisper_model_data:
            QMessageBox.warning(self, _("Warning"), _("No models available! Please download a model first."))
            return
            
        output_srt_path = f"{os.path.splitext(media_path)[0]}.srt"
        if os.path.exists(output_srt_path):
            reply = QMessageBox.question(self, _('File Exists'),
                                         _("Subtitle file '{}' already exists.\nDo you want to overwrite it?").format(os.path.basename(output_srt_path)),
                                         QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                                         QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.No:
                self.status_label.setText(_("Operation cancelled."))
                return

        self.process_button.setEnabled(False)
        self.stop_button.setEnabled(True)
        model_name = whisper_model_data.get("name")
        model_type = whisper_model_data.get("type")

        if model_type != 'local':
            QMessageBox.warning(self, _("Warning"), _("Subtitle generation only supports local models. Please select a local model."))
            self.process_button.setEnabled(True)
            self.stop_button.setEnabled(False)
            return

        model_path_or_name = os.path.join(app_config.get('paths.models', 'models'), model_name)
        if not os.path.exists(model_path_or_name):
            QMessageBox.critical(self, _("Error"), _("Local model file not found: {}").format(model_path_or_name))
            self.process_button.setEnabled(True)
            self.stop_button.setEnabled(False)
            return

        language = generation_opts.get("video_lang")
        translate = generation_opts.get("translate_to_english")
        
        self.worker = ProcessingWorker(media_path, model_path_or_name, language, translate)
        self.worker.progress.connect(self.update_status_label)
        self.worker.timing_updated.connect(self.update_timing_info)
        self.worker.finished.connect(self.on_processing_finished)
        self.worker.error.connect(self.on_processing_error)
        
        # Pass the filename as a unique identifier
        self.worker.setProperty("media_filename", os.path.basename(media_path))

        self.add_history_entry(os.path.basename(media_path), self.generation_options.model_combo.currentText(), _("Processing..."))
        self.worker.start()

    def update_status_label(self, message):
        self.status_label.setText(message)

    def update_timing_info(self, stage, elapsed_time):
        self.status_label.setText(_("{stage} took: {elapsed_time:.2f} s").format(stage=stage, elapsed_time=elapsed_time))

    def add_history_entry(self, filename, model, status, total_time=None):
        row_position = self.history_table.rowCount()
        self.history_table.insertRow(row_position)
        
        time_str = f"{total_time:.2f}" if total_time is not None else ""

        self.history_table.setItem(row_position, 0, QTableWidgetItem(filename))
        self.history_table.setItem(row_position, 1, QTableWidgetItem(model))
        self.history_table.setItem(row_position, 2, QTableWidgetItem(time_str))
        self.history_table.setItem(row_position, 3, QTableWidgetItem(status))
        self.history_table.scrollToBottom()

    def on_processing_finished(self, message, total_time):
        self.update_status_label(_("Success! Total time: {total_time:.2f} s").format(total_time=total_time))
        self.process_button.setEnabled(True)
        self.stop_button.setEnabled(False)
        QMessageBox.information(self, _("Success"), _("Processing completed successfully."))
        
        sender_worker = self.sender()
        media_filename = sender_worker.property("media_filename")
        self.update_history_status(media_filename, _("Success"), total_time)

    def on_processing_error(self, error_message):
        self.update_status_label(_("Processing failed."))
        self.process_button.setEnabled(True)
        self.stop_button.setEnabled(False)
        QMessageBox.critical(self, _("Processing Failed"), error_message)

        sender_worker = self.sender()
        media_filename = sender_worker.property("media_filename")
        self.update_history_status(media_filename, _("Failed"))

    def stop_processing(self):
        if self.worker and self.worker.isRunning():
            media_filename = self.worker.property("media_filename")
            self.worker.stop()
            self.status_label.setText(_("Stopping..."))
            self.stop_button.setEnabled(False)
            self.process_button.setEnabled(True)
            self.update_history_status(media_filename, _("Stopped"))

    def update_history_status(self, filename, status, total_time=None):
        for row in range(self.history_table.rowCount()):
            item = self.history_table.item(row, 0)
            # Match filename and current status "Processing..."
            if item and item.text() == filename and self.history_table.item(row, 3).text() == _("Processing..."):
                if total_time is not None:
                    self.history_table.setItem(row, 2, QTableWidgetItem(f"{total_time:.2f}"))
                self.history_table.setItem(row, 3, QTableWidgetItem(status))
                break

    def run_formatter_standalone(self):
        last_dir = app_config.get("paths.last_srt_dir", os.path.expanduser("~"))
        file_path, _filter = QFileDialog.getOpenFileName(
            self, _("Select SRT file to format"), last_dir, _("SRT Files (*.srt)"),
        )
        if not file_path: return
        app_config.set("paths.last_srt_dir", os.path.dirname(file_path), emit_signal=False)
        app_config.save(emit_signal=False)
        reply = QMessageBox.question(self, _('Confirm Action'),
                                     _("Are you sure you want to format the file '{}'?").format(os.path.basename(file_path)),
                                     QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                                     QMessageBox.StandardButton.No)
        if reply == QMessageBox.StandardButton.No: return
        success, message = format_srt_file_standalone(file_path)
        if success:
            QMessageBox.information(self, _("Success"), message)
        else:
            QMessageBox.critical(self, _("Failed"), message)

    